001 /*
002 * Copyright 2005 Stephen J. McConnell.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
013 * implied.
014 *
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018
019 package net.dpml.transit;
020
021 import java.rmi.RemoteException;
022 import java.util.EventObject;
023 import java.util.EventListener;
024 import java.util.Map;
025 import java.util.WeakHashMap;
026
027 import net.dpml.transit.monitor.LoggingAdapter;
028
029 import net.dpml.util.Logger;
030 import net.dpml.util.UnicastEventSource;
031 import net.dpml.util.EventQueue;
032
033 /**
034 * A abstract base class that established an event queue and handles event dispatch
035 * operations for listeners declared in classes extending this base class.
036 *
037 * @author <a href="http://www.dpml.net">Digital Product Meta Library</a>
038 * @version 1.0.1
039 */
040 public abstract class DefaultModel extends UnicastEventSource implements Disposable
041 {
042 // ------------------------------------------------------------------------
043 // state
044 // ------------------------------------------------------------------------
045
046 private Map m_listeners = new WeakHashMap();
047
048 // ------------------------------------------------------------------------
049 // constructor
050 // ------------------------------------------------------------------------
051
052 /**
053 * Creation of a new model.
054 * @param queue the event queue
055 * @param name the name used to construct a logging channel
056 * @exception RemoteException if a remote exception occurs
057 */
058 public DefaultModel( EventQueue queue, String name )
059 throws RemoteException
060 {
061 this( queue, getLoggerForCategory( name ) );
062 }
063
064 /**
065 * Creation of a new model.
066 * @param queue the event queue
067 * @param logger the assigned logging channel
068 * @exception NullPointerException if the supplied logging channel is null
069 * @exception RemoteException if a remote exception occurs
070 */
071 public DefaultModel( EventQueue queue, Logger logger )
072 throws NullPointerException, RemoteException
073 {
074 super( queue, logger );
075 }
076
077 // ------------------------------------------------------------------------
078 // DefaultModel
079 // ------------------------------------------------------------------------
080
081 /**
082 * Return the assigned logging channel.
083 * @return the logging channel
084 */
085 protected Logger getLogger()
086 {
087 return super.getLocalLogger();
088 }
089
090 /**
091 * Dispose of the model.
092 */
093 public synchronized void dispose()
094 {
095 EventListener[] listeners = getEventListeners();
096 for( int i=0; i < listeners.length; i++ )
097 {
098 EventListener listener = listeners[i];
099 removeListener( listener );
100 }
101 super.terminate();
102 getLogger().debug( "disposed" );
103 }
104
105 /**
106 * Enqueue an event for delivery to registered
107 * listeners unless there are no registered
108 * listeners.
109 *
110 * @param event the event object to add to the queue
111 * @param waitForCompletion if TRUE the implementation will apply
112 * the event to the event source event handler and return on
113 * copmpletion of evetn delivery
114 */
115 protected void enqueueEvent( EventObject event, boolean waitForCompletion )
116 {
117 if( m_listeners.size() > 0 )
118 {
119 getEventQueue().enqueueEvent( event, waitForCompletion );
120 }
121 }
122
123 /**
124 * Return a logging channel for the supplied name.
125 * @param name the name to use in construction of the logging channel
126 * @return the logging channel
127 */
128 static Logger getLoggerForCategory( String name )
129 {
130 if( null == name )
131 {
132 return new LoggingAdapter( "" );
133 }
134 else
135 {
136 return new LoggingAdapter( name );
137 }
138 }
139 }